#include "DL_ISDU_Handler.h"
#include "IO_LINK_Global_Param.h"
#include "AL_OD.h"
#include <string.h>
#include <stdio.h>
 
ISDU_PARAM_TypeDef ISDU_PARAM[PORT_NUM];
DL_ISDU_STATE_TYPE ISDU_STATE[PORT_NUM];


void ISDU_Init(void){
    for(uint8_t i=0;i<PORT_NUM;i++){
       ISDU_STATE[i]=ISDU_Inactive_0;
    }
}

 

 


/*******************输入Event**************************/
void Event_IH_Conf_ACTIVE(uint8_t Port){
    if(ISDU_STATE[Port]==ISDU_Inactive_0){
        
        ISDU_STATE[Port]=ISDU_Idle_1;
			  DL_ISDU_T1(Port);
    }
}

void Event_IH_Conf_INACTIVE(uint8_t Port){
   
      ISDU_STATE[Port]=ISDU_Inactive_0;
     
}

void Event_ISDUTrig(uint8_t Port){
    if(ISDU_STATE[Port]==ISDUResponse_5&&ISDU_PARAM[Port].ISDU_Trans_BOOL==ISDU_Transmssion_completed){
        
        ISDU_STATE[Port]=ISDU_Inactive_0;
			  DL_ISDU_T8(Port);
        return;
    }
    
    if(ISDU_PARAM[Port].ISDU_Trans_BOOL==ISDU_ParamRequest&&ISDU_STATE[Port]==ISDU_Idle_1){
        
        ISDU_STATE[Port]=subISDUWaitPage_1_1; //进入自定义子状态
			  DL_ISDU_T13(Port);
        return;
    }
    
     if(ISDU_PARAM[Port].ISDU_Trans_BOOL==ISDU_DL_ISDUTransport&&ISDU_STATE[Port]==ISDU_Idle_1){
        
        ISDU_STATE[Port]=ISDURequest_2;
			  DL_ISDU_T2(Port);
        return;
    }

    if(ISDU_STATE[Port]==ISDU_Idle_1){ //Idle
        DL_ISDU_T14(Port);
        //ISDU_STATE[Port]=ISDU_Idle_1;
        return;
    }
   
    if(ISDU_STATE[Port]==ISDURequest_2){
       
       ISDU_STATE[Port]=ISDURequest_2;
			DL_ISDU_T3(Port);
       return;
    }
    if(ISDU_STATE[Port]==ISDUWait_3){
      
       ISDU_STATE[Port]=subISDUWaitReturnISDU_3_1; //进入自定义子状态
			 DL_ISDU_T5(Port);
       return;
    }
    if(ISDU_STATE[Port]==ISDUResponse_5){
       
        ISDU_STATE[Port]=subISDUWaitReturnISUD_5_1;//进入自定义子状态
			 DL_ISDU_T7(Port);
        return;
    }
    
    
}





void Event_ISDU_Data_writen(uint8_t Port){
   if(ISDU_STATE[Port]==ISDURequest_2){
       
       ISDU_STATE[Port]=ISDUWait_3;
		   DL_ISDU_T4(Port);

   }
}



void Event_ISDU_ResponseStart(uint8_t Port){
   if(ISDU_STATE[Port]==ISDUWait_3){
     
     ISDU_STATE[Port]=ISDUResponse_5;
		 DL_ISDU_T6(Port);
   }
}

void Event_ISDU_Error(uint8_t Port){
    if(ISDU_STATE[Port]==ISDUWait_3){
        // DL_ISDU_T9(Port);
        ISDU_STATE[Port]=ISDUError_4;
    }
    if(ISDU_STATE[Port]==ISDUResponse_5){
       // DL_ISDU_T10(Port);
        ISDU_STATE[Port]=ISDUError_4;
    }
    
}

void Event_DL_ISDUAbort(uint8_t Port){
    if(ISDU_STATE[Port]==ISDURequest_2){
        ISDU_STATE[Port]=ISDUError_4;
       // DL_ISDU_T19(Port);
        return;
    }
    if(ISDU_STATE[Port]==ISDUWait_3){
        ISDU_STATE[Port]=ISDUError_4;
        //DL_ISDU_T17(Port);
        return;
    }

    if(ISDU_STATE[Port]==ISDUResponse_5){
        ISDU_STATE[Port]=ISDUError_4;
        //DL_ISDU_T18(Port);
        return;
    }
    
}

/************************转移动作************************************/

void DL_ISDU_T1(uint8_t Port){
 
}

void DL_ISDU_T2(uint8_t Port){
    //设定MC方向
    MC_Struct[Port].Dirction=Direction_Write;
    //初始化ISDU传输状态
    ISDU_PARAM[Port].ISDU_Trans_BOOL=ISDU_Transmssion_completed; 
    //初始化Point
    ISDU_PARAM[Port].ISDU_Pointer=0;
    //初始化FlowCtrl
    ISDU_PARAM[Port].ISDU_FlowCtrl=0;
    //构造OD.Req =设定 MC 和 OD
    //更新MC
    *(MC_Struct[Port].MC)=0x70U; 
    //更新OD
    memcpy(MC_Struct[Port].OD,&ISDU_BufferOut[Port][ISDU_PARAM[Port].ISDU_Pointer],MC_Struct[Port].ODLength);
    //更新Point,下次使用
    ISDU_PARAM[Port].ISDU_Pointer=ISDU_PARAM[Port].ISDU_Pointer+MC_Struct[Port].ODLength;
    //更新FlowCtrl，下次使用
    ISDU_PARAM[Port].ISDU_FlowCtrl++;
    if(ISDU_PARAM[Port].ISDU_FlowCtrl>0x0F){
       ISDU_PARAM[Port].ISDU_FlowCtrl=0;
    }
		Event_OD(Port);

}

void DL_ISDU_T3(uint8_t Port){
    //设定MC方向,防止其他通道篡改
    MC_Struct[Port].Dirction=Direction_Write;
   
    //更新MC
    *(MC_Struct[Port].MC)=ISDU_PARAM[Port].ISDU_FlowCtrl+0x60;
    //更新OD
    memcpy(MC_Struct[Port].OD,&ISDU_BufferOut[Port][ISDU_PARAM[Port].ISDU_Pointer],MC_Struct[Port].ODLength);

     //更新FlowCtrl，下次使用
    ISDU_PARAM[Port].ISDU_FlowCtrl++;
    if(ISDU_PARAM[Port].ISDU_FlowCtrl>0x0F){
       ISDU_PARAM[Port].ISDU_FlowCtrl=0;
    }
		
    //判断是否发送完毕
    if(ISDU_PARAM[Port].ISDU_Pointer>=ISDU_PARAM[Port].ISDUBufferOutLen){
        //发送完毕
        Event_ISDU_Data_writen(Port);
    }else{  
			       //更新Point,下次使用
        ISDU_PARAM[Port].ISDU_Pointer=ISDU_PARAM[Port].ISDU_Pointer+MC_Struct[Port].ODLength;
			  Event_OD(Port);
		}
}


 

void DL_ISDU_T4(uint8_t Port){
    //启动ISDU定时器
    StartISDUTimer(Port);
    //将MC切换到Read
    MC_Struct[Port].Dirction=Direction_Read; 
    //初始化接收OD
    *MC_Struct[Port].OD=0x01;//
}

void DL_ISDU_T5(uint8_t Port){
    //设定MC方向,防止其他通道篡改
      MC_Struct[Port].Dirction=Direction_Read; 
    // 继续等待ISDU OD.Re
      *(MC_Struct[Port].MC)=0xF0;
      Event_OD(Port);

}

 

//自定义子子状态subISDUwait_3的转移函数，当发生Event_return_OD时触发
//此函数解析ISDU，判断是否开始接收
void DL_ISDU_T5_1(uint8_t Port){
      //首先将接收的OD存储到ISDU输入缓冲
    memcpy(&ISDU_BufferIn[Port][0],MC_Struct[Port].OD,MC_Struct[Port].ODLength);
        
       uint8_t I_Service,LEN,ExtLength;
       I_Service=(*MC_Struct[Port].OD)&0xF0;
       LEN=(*MC_Struct[Port].OD)&0x0F;
      
      //解析接收的ISDU，判断是否一次性读取了ISDU
       switch (I_Service)
       {
       case 0x00:
           if(LEN==0x01){ //接收到OD是0x01，即处于等待ISDU回复状态
           
              break;
           }
       case 0x50:
           ISDU_PARAM[Port].ISDUBUfferInLen=2;
           ISDU_PARAM[Port].ISDU_Cnf=ISDU_Cnf_Positive;
			 
            
           //判断是否一次接收完毕
           if(ISDU_PARAM[Port].ISDUBUfferInLen<=MC_Struct[Port].ODLength){
               ISDU_PARAM[Port].ISDU_Trans_BOOL=ISDU_Transmssion_completed;               
           }           
              
           Event_ISDU_ResponseStart(Port);
           break;
       case 0x40:
           ISDU_PARAM[Port].ISDUBUfferInLen=4;
           ISDU_PARAM[Port].ISDU_Cnf=ISDU_Cnf_Nagtive;
           uint16_t MSB,LSB;
           //判断是否一次接收完毕
           if(ISDU_PARAM[Port].ISDUBUfferInLen<=MC_Struct[Port].ODLength){
              //已经接收完毕情况下
               MSB=(uint16_t)ISDU_BufferIn[Port][1];
               LSB=(uint16_t)ISDU_BufferIn[Port][2];
              //提取ErrorType
               ISDU_PARAM[Port].ISDU_ErrorType=(MSB<<8)|LSB; 
               Event_ISDU_Error(Port);
               return;
                            
           }
       
           Event_ISDU_ResponseStart(Port);
           break;
       case 0xD0:
           
           
           if(LEN!=0x01){    //如果没有Extlength    
               ISDU_PARAM[Port].ISDUBUfferInLen=LEN;  //获得ExtLength               
               ISDU_PARAM[Port].ISDUData=&ISDU_BufferIn[Port][1]; //获取ISDU的数据指针 
               ISDU_PARAM[Port].ISDUDataLen=ISDU_PARAM[Port].ISDUBUfferInLen-2; //获得数据长度
             
               //判断是否一次接收完毕
               if(ISDU_PARAM[Port].ISDUBUfferInLen<=MC_Struct[Port].ODLength){
                   ISDU_PARAM[Port].ISDU_Trans_BOOL=ISDU_Transmssion_completed;               
               }
               
           }else{//如果有Extlength
               //获取ISDU的数据指针
               ISDU_PARAM[Port].ISDUData=&ISDU_BufferIn[Port][2];
               //判断能否获得ExtLength
                if(MC_Struct[Port].ODLength>1){
                    ISDU_PARAM[Port].ISDUBUfferInLen=*(MC_Struct[Port].OD+1);
                    ISDU_PARAM[Port].ISDUDataLen=ISDU_PARAM[Port].ISDUBUfferInLen-3; //获得数据长度
                    ISDU_PARAM[Port].ISDUData=&ISDU_BufferIn[Port][2]; //数据指针(地址)
                      //判断是否一次接收完毕
                     if(ISDU_PARAM[Port].ISDUBUfferInLen<=MC_Struct[Port].ODLength){
                      ISDU_PARAM[Port].ISDU_Trans_BOOL=ISDU_Transmssion_completed;               
                      }
                }
           }
         
           Event_ISDU_ResponseStart(Port);
           break;
       case 0xC0:
          ISDU_PARAM[Port].ISDUBUfferInLen=4;
          //判断是否一次接收完毕
           if(ISDU_PARAM[Port].ISDUBUfferInLen<=MC_Struct[Port].ODLength){
                  //已经接收完毕情况下
               MSB=(uint16_t)ISDU_BufferIn[Port][1];
               LSB=(uint16_t)ISDU_BufferIn[Port][2];
              //提取ErrorType
               ISDU_PARAM[Port].ISDU_ErrorType=(MSB<<8)|LSB; 
               //通过T9转移到ISDUError_4状态
               Event_ISDU_Error(Port);
               return;             
           }
            
           Event_ISDU_ResponseStart(Port);
           break;
       
           
       default:  //接收出错
            
             
            Event_ISDU_Error(Port);
           break;
       }
}

void DL_ISDU_T6(uint8_t Port){
    //停止ISDU Timer
    StopISDUTimer(Port); 

    //初始化FlowCtrl Pointer,下次T7调用时候使用
    ISDU_PARAM[Port].ISDU_Pointer=MC_Struct[Port].ODLength;
    ISDU_PARAM[Port].ISDU_FlowCtrl=0x01;

}

//自定义子子状态subISDUwait_3的转移函数，当发生Event_return_OD时触发
//此函数解析ISDU，判断是否结束接收
void DL_ISDU_T7_1(uint8_t Port){
      //首先将接收的OD存储到ISDU输入缓冲
    memcpy(&ISDU_BufferIn[Port][0],MC_Struct[Port].OD,MC_Struct[Port].ODLength);
    //获取Extlength
    if(ISDU_PARAM[Port].ISDUBUfferInLen==0x01){
        ISDU_PARAM[Port].ISDUBUfferInLen=ISDU_BufferIn[Port][1]; //ExtLength
        ISDU_PARAM[Port].ISDUDataLen=ISDU_PARAM[Port].ISDUBUfferInLen-3; //获得数据长度
        ISDU_PARAM[Port].ISDUData=&ISDU_BufferIn[Port][2]; //数据指针(地址)

        
    }

     //更新Point,下次使用
    ISDU_PARAM[Port].ISDU_Pointer=ISDU_PARAM[Port].ISDU_Pointer+MC_Struct[Port].ODLength;
     //更新FlowCtrl，下次使用
    ISDU_PARAM[Port].ISDU_FlowCtrl++;
    if(ISDU_PARAM[Port].ISDU_FlowCtrl>0x0F){
       ISDU_PARAM[Port].ISDU_FlowCtrl=0;
    }
    
    //判断是否接收结束   
    if(ISDU_PARAM[Port].ISDU_Pointer>=ISDU_PARAM[Port].ISDUBufferOutLen){
      //接收结束，开始解析ISDU
  
        //获取I_Service
         uint8_t I_Service=ISDU_BufferIn[Port][0]&0xF0;
         if(I_Service==0x40||I_Service==0xC0){ //conf为负
              uint16_t MSB,LSB;
               MSB=(uint16_t)ISDU_BufferIn[Port][1];
               LSB=(uint16_t)ISDU_BufferIn[Port][2];
              //提取ErrorType
               ISDU_PARAM[Port].ISDU_ErrorType=(MSB<<8)|LSB; 
               //通过T9转移到ISDUError_4状态
               Event_ISDU_Error(Port); // ISDU负反馈
         }else{
            
             ISDU_PARAM[Port].ISDU_Trans_BOOL=ISDU_Transmssion_completed; //ISDU正反馈
         }

        
        
    }
       
      
}

void DL_ISDU_T7(uint8_t Port){
    //设定MC方向,防止其他通道篡改
      MC_Struct[Port].Dirction=Direction_Read; 
    //构造OD.Req
    
      *(MC_Struct[Port].MC)=0xE0+ISDU_PARAM[Port].ISDU_FlowCtrl;
      Event_OD(Port);
  
}

void DL_ISDU_T8(uint8_t Port){
    //构造 Idle OD.Req
    
      *(MC_Struct[Port].MC)=0xF1;
      Event_OD(Port);  
	   
    //待更新，暂时停止此动作 Event_DL_ISDUTransport_Cnf(ISDU_PARAM[Port].ISDUData,ISDU_PARAM[Port].ISDUDataLen,ISDU_PARAM[Port].ISDU_ErrorType);
     

}

void DL_ISDU_T11(uint8_t Port){
    //构造 OD.Req (R  ISDU FlowCtrl=ABort)
     *(MC_Struct[Port].MC)=0xFF;
      Event_OD(Port);  
	  
     //待更新，暂时停止此动作 Event_DL_ISDUTransport_Cnf(NULL,0,ISDU_PARAM[Port].ISDU_ErrorType);
}

void DL_ISDU_T13(uint8_t Port){
   if(ISDU_PARAM[Port].ISDU_Channel==Channel_ParamRequest_Read){
         MC_Struct[Port].Dirction=Direction_Read;
       //构造OD.Req
       *(MC_Struct[Port].MC)=0xA0+PAGE_BufferOut[Port][0];
		   
       //Event_DL_ReadParam_Cnf(Port); 在DL_ISDU_T13_1中调用

   }else if(ISDU_PARAM[Port].ISDU_Channel==Channel_ParamRequest_Write){
       MC_Struct[Port].Dirction=Direction_Write;
       //构造OD.Req
       *(MC_Struct[Port].MC)=0x20+PAGE_BufferOut[Port][0];
       
        *(MC_Struct[Port].OD)=PAGE_BufferOut[Port][1];
   }
   Event_OD(Port);

}

//自定义子状态的转移函数
void DL_ISDU_T13_1(uint8_t Port){
    if(ISDU_PARAM[Port].ISDU_Channel==Channel_ParamRequest_ISDU_Read){
        PAGE_BufferIn[Port]=*MC_Struct[Port].OD;
        Service_DL_ReadParam_Cnf(Port,PAGE_BufferIn[Port]);
    }else{
         Service_DL_WriteParam_Cnf(Port);
    }
    
}

void DL_ISDU_T14(uint8_t Port){
    //ISDU Idle状态
    MC_Struct[Port].Dirction=Direction_Read;    
    *(MC_Struct[Port].MC)=0xF1;
    Event_OD(Port);
}

 
